import EventMgr from "../../manager/EventMgr"
import { SdkEvent, SdkRewardVideoState } from "../SdkConstants"
import SdkUtil from "../SdkUtil"
import SdkBase from "./SdkBase"


enum RecordState { Free, Recording, Pause }


export default class SdkBytedance extends SdkBase {
    private conf: ISdkConf
    private env: IBytedance

    private rewardVideo: IBytedanceRewardVideo
    private recorder: IBytedanceGameRecorderManager

    private _recordState: RecordState = RecordState.Free
    private _recordTime: number = 0
    private _recordVideoPath: string


    public constructor(conf: ISdkConf) {
        super()

        this.conf = conf
        this.env = window['tt']

        if (this.env.onShow) {
            this.env.onShow((ret: IBytedanceShowRet) => {
                if (ret && ret.scene == '021036') {
                    // 从侧边栏进入游戏
                    EventMgr.emit(SdkEvent.BytedanceSidebarInto)
                }
            })
        }

        if (this.env.getEnvInfoSync) {
            const envInfo = this.env.getEnvInfoSync()
            this._bdEnvType = envInfo['microapp']['envType']
        }

        this.recorder = this.env.getGameRecorderManager()
        this.recorder?.onError((msg: string) => this.onRecorderError(msg))
    }


    public getLaunchOptionsSync(): Object {
        return this.env['getLaunchOptionsSync']()
    }
    
    public share(title?: string, imageUrl?: string, templateId?: string, query?: string) {
        const param: IBytedanceShareParam = { title: this.conf.gameName, desc: title }

        imageUrl && (param['imageUrl'] = imageUrl)
        templateId && (param['templateId'] = templateId)
        query && (param['query'] = query)


        const option: IBytedanceShareParam = param

        this.env.shareAppMessage(option)
    }


    public rewardVideoPlay(id: string, cb: (state: number, ret?: any) => void) {
        if (this.rewardVideo && this.rewardVideo.destroy) {
            this.rewardVideo.destroy().
                then(() => {
                    this.rewardVideo = null
                    this.rewardVideoPlay(id, cb)
                }).
                catch((err: any) => cb(SdkRewardVideoState.PlayError, 'bytedance rewardVideo destroy err:' + JSON.stringify(err)))

            return
        }

        this.rewardVideo = this.env.createRewardedVideoAd({ adUnitId: id })
        if (!this.rewardVideo) {
            cb(SdkRewardVideoState.PlayError, 'bytedance rewardVideo createRewardedVideoAd return null')
            return
        }

        const closeCall = (ret: IBytedanceRewardVideoCloseRet) => {
            if (!ret || ret.isEnded) {
                cb(SdkRewardVideoState.CloseReward)
            } else {
                cb(SdkRewardVideoState.Close)
            }

            this.rewardVideo.offClose(closeCall)
            this.rewardVideo.offError(errorCall)
        }

        const errorCall = (err: any) => {
            cb(SdkRewardVideoState.PlayError, 'bytedance rewardVideo onError err:' + JSON.stringify(err))

            this.rewardVideo.offClose(closeCall)
            this.rewardVideo.offError(errorCall)
        }

        this.rewardVideo.onClose(closeCall)
        this.rewardVideo.onError(errorCall)

        this.rewardVideo.show().then(() => cb(SdkRewardVideoState.PlaySuccess))
    }


    public get recordIsSupport(): boolean { return true }

    public recordStart(duration: number, stopCb?: Function) {
        if (this._recordState != RecordState.Free) return

        this._recordState = RecordState.Recording
        this._recordVideoPath = null

        this.recorder?.onStart(() => {
            this._recordTime = SdkUtil.unixtime()
            console.log(`Bytedance 录屏开始 duration:${duration},recordTime:${this._recordTime}`)
        })

        this.recorder?.onStop((ret: IBytedanceRecorderRet) => {
            if (ret) {
                this._recordVideoPath = ret.videoPath
            }

            this._recordState = RecordState.Free
            this._recordTime = SdkUtil.unixtime() - this._recordTime

            console.log(`Bytedance 录屏完成 unixtime:${SdkUtil.unixtime()},recordTime:${this._recordTime}`)

            stopCb && stopCb()
        })

        this.recorder?.start({ duration: duration })
    }

    public recordStop() {
        if (this._recordState != RecordState.Recording && this._recordState != RecordState.Pause) return

        this.recorder?.stop()
    }

    public recordPause() {
        if (this._recordState != RecordState.Recording) return

        this._recordState = RecordState.Pause
        this.recorder?.pause()
    }

    public recordResume() {
        if (this._recordState != RecordState.Pause) return

        this._recordState = RecordState.Recording
        this.recorder?.resume()
    }

    public recordShare(needTime: number, param?: Object): string {
        if (!this._recordVideoPath) return '录屏失败：录屏未结束'
        if (this._recordTime < needTime) return `录屏失败：录屏时长低于 ${needTime} 秒`

        this.shareVideo(this._recordVideoPath)

        return null
    }


    private onRecorderError(msg: string) {
        console.error(`SdkBytedance.onRecorderError msg:${msg}`)
    }

    private shareVideo(videoPath: string) {
        const options: IBytedanceShareParam = {
            channel: 'video',
            extra: { videoPath, withVideoId: true, hashtag_list: [this.conf.gameName] },
            success: () => this.alert('分享', '视频分享成功'),
        }

        this.env.shareAppMessage(options)
    }

    private alert(title: string, content: string) {
        const options = {
            title,
            content,

            showCancel: false
        }

        this.env.showModal(options)
    }


    /**
     * 使手机发生较短时间的振动。Android 震动时间为 30ms，iOS 震动时间为 15ms。
     */
    public vibrateShort(_type: string) {
        if (!this.env['vibrateShort']) return

        this.env['vibrateShort']()
    }

    public vibrateLong() {
        if (!this.env['vibrateLong']) return

        this.env['vibrateLong']()
    }
}
